﻿using System;
using System.IO;
using System.Text;

namespace CoreLibrary {

    public sealed class IOUtil {

        public static string ReadStringAndClose(Stream stream) {
            using (stream) {
                return Encoding.UTF8.GetString(Read(stream));
            }
        }

        public static string ReadStringAndClose(Stream stream, Encoding encoding) {
            using (stream) {
                return encoding.GetString(Read(stream));
            }
        }

        public static byte[] Read(Stream stream) {
            if (stream.CanSeek) {
                stream.Position = 0;
            }
            return Read(stream, 0);
        }

        public static byte[] Read(Stream stream, int initialLength) {
            if (initialLength < 1) {
                initialLength = 32768; // 32k
            }

            var buffer = new byte[initialLength];
            var read = 0;

            if (stream != null) {
                int chunk;
                while ((chunk = stream.Read(buffer, read, buffer.Length - read)) > 0) {
                    read += chunk;
                    if (read == buffer.Length) {
                        int nextByte = stream.ReadByte();

                        // End of stream? If so, we're done
                        if (nextByte == -1) {
                            return buffer;
                        }

                        // Nope. Resize the buffer, put in the byte we've just
                        // read, and continue
                        var newBuffer = new byte[buffer.Length * 2];
                        Array.Copy(buffer, newBuffer, buffer.Length);
                        newBuffer[read] = (byte)nextByte;
                        buffer = newBuffer;
                        read++;
                    }
                }
            }

            var ret = new byte[read];
            Array.Copy(buffer, ret, read);
            return ret;
        }
    }
}